package cn.wgx.commons.interceptor;

import cn.wgx.commons.exception.cn.TooFastRequestException;
import cn.wgx.commons.util.Servlets;
import cn.wgx.commons.util.SpringContextHolder;
import cn.wgx.modules.sys.util.UserUtil;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
import java.util.concurrent.TimeUnit;

/**
 * 防止同一 api 请求过快发生
 *
 */
public class RequestTimeLimit implements HandlerInterceptor {


    private static RedisTemplate redisTemplate = SpringContextHolder.getBean("redisTemplate");

    //非get请求最小间隔, 毫秒
    private static int limit_post = 1000;

    //get请求最小间隔, 毫秒
    private static int limit_get = 50;

    private static String []filter = {"/api/fileupload/addAppend"};

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String requestURI = request.getRequestURI();

        // 如果是请求不是api请求
        if (requestURI != null && !requestURI.contains("/api/")){
            return true;
        }
        // 如果是静态文件
        if (Servlets.isStaticFile(requestURI)){
            return true;
        }
        for(String s: filter){
            if(requestURI.contains(s)){
                return true;
            }
        }
        String method = request.getMethod();
        Serializable id = UserUtil.getSession().getId();
        if(requestURI != null && method != null && id != null){
            ValueOperations valueOperations = redisTemplate.opsForValue();
            String o = id + requestURI + method;
            if(valueOperations.get(o) == null){
                if("GET".equals(method.toUpperCase())){
                    valueOperations.set(o,0, limit_get, TimeUnit.MILLISECONDS);
                }else{
                    valueOperations.set(o,0, limit_post, TimeUnit.MILLISECONDS);
                }
                return true;
            }else{
                throw new TooFastRequestException();
            }
//            hashOperations.put();
        }

        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}
